起因:
最近公司项目的公众号有些接口返回数据的时间很久。
原因很简单,因为是Mysql数据库而且数据量大概在500W条数据,接口响应时间在4S到5S.
体验感太差劲了。so,我们来改造下。
改造思路:
1.SQL优化。
此接口的SQL关联两张表,主订单,副产品,副货道表
- a. 先把订单表中多加入个货道号的字段,减少一张表的关联。
- b. 减少不需要的返回字段
这样改造后,接口返回会快一丢丢。效果不明显
2.我们直接把热点数据加入缓存中。
我们常用的缓存是 redis, mongdb 等。 但是他们都有网络开销。
我决定用本地的cache来优化。
开始是准备用项目里原来同事写的一个全局变量类的,后来想起来在极客时间看的高并发编程40问里面说的。 推荐使用google的 Google Guava 做本地缓存。
实现流程:
- 项目启动后,定时任务把数据塞入到缓存
- 从缓存中把数据拿出来返回给前端
- 有定时任务按时刷新缓存中的数据
不多说上代码:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.math.BigDecimal;
/**
* guava本地缓存工具类
* @author bobo
*/
public final class GuavaCacheUtil {
private static CacheBuilder<Object, Object> cacheBuilder
= CacheBuilder.newBuilder()
.maximumSize(10000)
.initialCapacity(10)
.recordStats();
private static Cache<String, Object> cache;
static {
cache = cacheBuilder.build();
}
private GuavaCacheUtil() {
}
/**
* 添加缓存
*
* @param key
* @param value
*/
public static void set(String key, Object value) {
cache.put(key, value);
}
/**
* 删除缓存
*
* @param key
*/
public static void del(String key) {
cache.invalidate(key);
}
/**
* 根据key取得缓存对象
*
* @param key
* @return
*/
public static Object get(String key) {
return cache.getIfPresent(key);
}
public static String getStr(String key) {
return get(key).toString();
}
public static int getInt(String key) {
Object value = get(key);
if (value instanceof Integer) {
return Integer.valueOf(value.toString());
}
return 0;
}
public static BigDecimal getBigDecimal(String key) {
Object value = get(key);
if (value instanceof BigDecimal) {
return new BigDecimal(value.toString());
}
return BigDecimal.ZERO;
}
Cache<String, String> statsCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.initialCapacity(1000)
.recordStats() //开启统计信息开关
.build();
}
/** 业务中使用 **/
@RequestMapping("getAll")
public Object getAll(){
List<BbaLog> bbaLogs = bbaLogMapper.findAny();
if (bbaLogs.size()>0){
GuavaCacheUtil.set("bba_log",bbaLogs);
Object cacheLog = GuavaCacheUtil.get("bba_log");
List<BbaLog> bbaLogList = (List<BbaLog>) cacheLog;
for (BbaLog bbaLog : bbaLogList){
System.err.println(bbaLog.getId());
}
return bbaLogList;
}else {
return "没数据";
}
}
其实和别的Cache差不多。但是性能比他们高很多,我只是简单的使用。 现在改造后,接口响应是1.99s,返回8000条数据。 但是实际接口数据的返回是87ms,但是8000数据Content Download的时间是1.90s. 优化下缓存中返回数据带分页效果,这样速度肯定会更快。 暂时还没优化完。 优化完后应该可以控制在100ms以内。
项目中还有挺多地方可以优化。 慢慢去修改吧、只要还给时间